<template>
  <el-dialog
    v-model="dialogVisible"
    :title="dialogTitle"
    width="1000px"
    @close="closeDialog"
  >
    <el-table
      ref="permTable"
      :data="permsList"
      row-key="pkPerm"
      style="width: 100%"
      :tree-props="{ children: 'downs' }"
      @selection-change="handleSelectionChange"
    >
      <el-table-column
        :selectable="(row) => !whiteRotes.includes(row.pkPerm)"
        type="selection"
        width="80"
      />
      <el-table-column label="权限编码" mix-width="120" prop="permCode" />
      <el-table-column label="权限名称" mix-width="120" prop="permName" />
      <el-table-column label="操作端" mix-width="180" prop="applyTo">
        <template #default="scope">
          {{ scope.row.applyTo === 'web' ? 'PC端' : '移动端' }}
        </template>
      </el-table-column>
      <el-table-column label="权限说明" mix-width="180" prop="roleMemo" />
    </el-table>
    <template #footer>
      <el-button @click="closeDialog">取 消</el-button>
      <el-button type="primary" @click="save">确 定</el-button>
    </template>
  </el-dialog>
</template>
<script setup>
  // ---- import 开始 ----
  import { findPermByRoleApi, getPermissionApi } from '@/api/comdesk/perm'
  import { changeRolePermApi } from '@/api/comdesk/role'
  const $baseLoading = inject('$baseLoading')
  const $baseMessage = inject('$baseMessage')
  // ---- import 结束 ----
  // ---- dom ref 开始 ----
  const permTable = ref(null)
  // ---- dom ref 结束 ----
  const permsList = ref([])
  const whiteRotes = ref([])
  let hasPerms = []

  const dialogVisible = ref(false)
  const dialogTitle = ref('权限变更')
  const roleData = ref()
  let selectedRows = []
  let selectedCodes = []

  const toOpenChangePerm = async (row) => {
    dialogVisible.value = true
    roleData.value = row
    // 获取当前角色权限
    const load = $baseLoading()

    const getPermDataRes = await getPermissionApi({}).finally(() =>
      load.close()
    )
    if (getPermDataRes && getPermDataRes.code === 2000) {
      permsList.value = getPermDataRes.data
    } else {
      load.close()
      $baseMessage(
        getPermDataRes && getPermDataRes.msg
          ? getPermDataRes.msg
          : '数据获取失败,请重试',
        'error'
      )
      closeDialog()
    }
    const res = await findPermByRoleApi({ pkRole: row.pkRole }).catch(
      load.close
    )
    load.close()
    if (res && res.code === 2000) {
      hasPerms = [...whiteRotes.value, ...res.data]
      // 筛选权限
      getFilterPerms(permsList.value)
      setCurrentSelected()
    } else {
      $baseMessage(res && res.msg ? res.msg : '数据获取失败,请重试', 'error')
    }
  }
  const getFilterPerms = (perms) => {
    perms.forEach((permItem) => {
      if (hasPerms.includes(permItem.pkPerm)) {
        selectedRows.push(permItem)
      }
      if (permItem.downs && permItem.downs.length > 0) {
        getFilterPerms(permItem.downs)
      }
    })
  }

  const handleSelectionChange = (perms) => {
    selectedRows = perms
    selectedCodes = []
    perms.forEach((perm) => {
      selectedCodes.push(perm.pkPerm)
    })
  }

  const setCurrentSelected = () => {
    if (selectedRows && selectedRows.length > 0) {
      selectedRows.forEach((selectedRow) => {
        permTable.value.toggleRowSelection(selectedRow, undefined)
      })
    }
  }

  let allSelectedRows = []
  let allSelectedCodes = []
  const save = async () => {
    // 筛选功能
    allSelectedRows = []
    allSelectedCodes = []
    getAllSelectedChildAndParent(permsList.value)
    const load = $baseLoading()
    const res = await changeRolePermApi({
      pkRole: roleData.value.pkRole,
      perms: allSelectedCodes,
    }).catch(() => {
      load.close()
    })
    load.close()
    if (res && res.code === 2000) {
      $baseMessage('修改成功', 'success')
      closeDialog()
    } else {
      $baseMessage(res && res.msg ? res.msg : '修改成功', 'error')
    }
  }
  const getAllSelectedChildAndParent = (data) => {
    let flag = false
    data.forEach((perm) => {
      if (perm.downs && perm.downs.length > 0) {
        flag = getAllSelectedChildAndParent(perm.downs)
      }
      if (selectedCodes.includes(perm.pkPerm) || flag) {
        allSelectedRows.push(perm)
        allSelectedCodes.push(perm.pkPerm)
        flag = true
      }
    })
    return flag
  }

  const closeDialog = () => {
    roleData.value = null
    dialogVisible.value = false
    selectedRows = []
    hasPerms = []
  }
  defineExpose({ toOpenChangePerm })
</script>
